/**
 * Copyright (C)  Gadglet .
 *
 * This file is part of Gadglet
 *
 * Gadglet is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Gadglet is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Gadglet. If not, see <http://www.gnu.org/licenses/>.
 */

package com.gadglet.gadgets.personalNotes.server;

import java.util.HashMap;
import java.util.List;
import java.util.logging.Logger;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import com.gadglet.core.GadgletRequestWrapper;
import com.gadglet.core.GadgletResponse;
import com.gadglet.core.GadgletResponse.ContentRecord;
import com.gadglet.core.MingletRequestHandler;
import com.gadglet.core.RequestException;
import com.gadglet.data.SharedItemReff;
import com.gadglet.data.UserProfile;
import com.gadglet.data.UserProfilesUtils;
import com.gadglet.data.utils.ContentItemHelper;
import com.gadglet.data.utils.HasMoreItems;
import com.gadglet.data.utils.PMF;
import com.gadglet.gadgets.personalNotes.shared.Params;
import com.gadglet.params.FieldErrorTypes;
import com.gadglet.params.GadgetViewState;
import com.gadglet.params.ProfileFields;
import com.gadglet.params.ReqErrorTypes;
import com.gadglet.params.SharingType;

/**
 * Gadglet server side handler class. This class is the Gadget server side
 * entrypoint loaded by Gadglet platform for every request. When loaded,
 * UserProfile (Minglet)is already loaded to the session and accessible by
 * GadgletRequestWrapper methods
 * The class name MUST be "RequestHandler" unless you define it specifically 
 * when defining the Gadget with the admin tool
 * 
 * Gadglet platform will invoke the correct methods according to the requested
 * "ReqActionTypes"
 * 
 * @see com.gadglet.params.ReqActionTypes
 * @see MingletRequestHandler
 */
public class RequestHandler extends MingletRequestHandler {
	Logger log = Logger.getLogger(this.getClass().getName());

	private final ContentItemHelper helper = new ContentItemHelper();

	
	/**
	 * Delete all Personal notes (owned y the current user)
	 * 
	 * This method is an example of custom RequestHandler method activated 
	 * by the use of client method 
	 * <p>
	 *@see com.gadglet.client.gwt.core.GadgletQuery.setContentActoinName(String contentActoinName)
	 * */
	
	@SuppressWarnings("unchecked")
	public void doDeleteAll(GadgletRequestWrapper request, GadgletResponse response)
	 {
		
		PersistenceManager pm;		
		List <PersonalNotesData> items;
		
		
		pm = PMF.get().getPersistenceManager();
		Query qry = pm.newQuery(PersonalNotesData.class);
		
		qry.declareParameters("String ownerIdParam");
		qry.setFilter(" ownerId == ownerIdParam");
		
		
		try {
			// for some reason doesn't work with transaction
			
			items = (List<PersonalNotesData>) qry.execute(request.getCurrentUserId());
			
			pm.deletePersistentAll(items);
			
		} catch (Exception e) {
			log.warning(e.getMessage());
		
		} finally {
	
			pm.close();
		}
	
		 
	 }
	/**
	 * Delete Personal note
	 * */
	@Override
	public void doDelete(GadgletRequestWrapper request, GadgletResponse response)
			throws RequestException {
		helper.delete(request, PersonalNotesData.class);
	}

	/**
	 * Share Personal note with a friend
	 * */
	@Override
	public void doShare(GadgletRequestWrapper request, GadgletResponse res)
			throws RequestException {

		helper.shareItem(request, PersonalNotesData.class);
	}

	/**
	 * Return a list of friends and their sharing definition for a given content
	 * item
	 * */
	@Override
	public void doSharedList(GadgletRequestWrapper request, GadgletResponse res)
			throws RequestException {

		PersonalNotesData item = (PersonalNotesData) helper.getSingleItemByKey(
				request, PersonalNotesData.class);

		if (!item.isOwnedByMe(request))
			throw new RequestException(ReqErrorTypes.UNAUTHORIZED_OPERATION);

		item.getFriendsSharing(request, res);

	}

	/**
	 * Add a new Personal note
	 * <p>
	 * Example:
	 * <li>Sending field level error code to the client (empty content)
	 * <li>Sending field level error code to the client (content length)
	 * <li>Sending field level error code to the client (value not valid)
	 * <li>Sending error code to the client (user quota)
	 * */
	@Override
	public void doAdd(GadgletRequestWrapper request, GadgletResponse response)
			throws RequestException {

		String msg = request.getParameter(Params.MESSAGE.getParamName());
		if (msg == null || msg.isEmpty()) {
			response.addFieldError(Params.MESSAGE.getParamName(),
					FieldErrorTypes.FIELD_IS_EMPTY);
			throw new RequestException(ReqErrorTypes.MISSING_ARGUMENT);
		}
		// String field is limited to 500 chars...
		if (msg.length() > 499)
			throw new RequestException(ReqErrorTypes.CONTENT_EXCEED_MAX_LENGTH);

		final int maxItemsForFreeAcount = 25;
		int priority = 0;

		try {
			priority = Integer.parseInt(request.getParameter(Params.PRIORITY
					.getParamName()));
		} catch (NumberFormatException e) {
			log.warning(e.getMessage());
			response.addFieldError(Params.PRIORITY.getParamName(),
					FieldErrorTypes.VALUE_NOT_VALID);
			throw new RequestException(ReqErrorTypes.MISSING_ARGUMENT);
		}

		HasMoreItems hasMore = new HasMoreItems();
		List<PersonalNotesData> items = (List<PersonalNotesData>) helper
				.getOwnerItems(request, PersonalNotesData.class,
						request.getFilterBy(),
						request.getFilterByDeclaration(), null, null, 0, 1000,
						hasMore);
		if (items.size() >= maxItemsForFreeAcount)
			throw new RequestException(
					ReqErrorTypes.ITEMS_NUM_EXCEED_USER_QUOTA);

		PersonalNotesData item = new PersonalNotesData(
				request.getTrustedParameterValue("personalNotesMessage", true),
				priority, request);

		helper.saveNew(item);
	}
	/**
	 * Update Personal note
	 * */
	@Override
	public void doUpdate(GadgletRequestWrapper request, GadgletResponse response)
			throws RequestException {
		// check imput
		String msg = request.getParameter(Params.MESSAGE.getParamName());

		if (msg == null || msg.isEmpty()) {
			response.addFieldError(Params.MESSAGE.getParamName(),
					FieldErrorTypes.FIELD_IS_EMPTY);

			throw new RequestException(ReqErrorTypes.MISSING_ARGUMENT);
		}
		PersonalNotesData item = (PersonalNotesData) helper.getSingleItemByKey(
				request, PersonalNotesData.class);
		item.setPersonalNotesMessage(msg);
		helper.updated(null, item, request);
	}

	/**
	 * Return a list personal notes 
	 * */
	@Override
	public void doView(GadgletRequestWrapper request, GadgletResponse response)
			throws RequestException {
		HasMoreItems hasMore = new HasMoreItems();
		int returnedItems;
		HashMap<String, Object> params = null;
		if (request.getParameter(Params.PRIORITY.getParamName()) != null
				&& !request.getParameter(Params.PRIORITY.getParamName())
						.isEmpty()) {
			params = new HashMap<String, Object>();
			try {
				params.put(Params.PRIORITY.getParamName(), Integer
						.parseInt(request.getParameter(Params.PRIORITY
								.getParamName())));
			} catch (NumberFormatException e) {

				log.warning(e.getMessage());
				throw new RequestException(ReqErrorTypes.MISSING_ARGUMENT);
			}
		}

		List<PersonalNotesData> items = (List<PersonalNotesData>) helper
				.getSharedItems(request, PersonalNotesData.class,
						request.getFilterBy(),
						request.getFilterByDeclaration(), params,
						request.getOrderBy(), request.getStartFrom(),
						request.getItemNum(), hasMore);

		// if the request is for 3 items the method getOwnerItems will try to
		// find 4 and then remove the last...
		returnedItems = items.size();
		if (hasMore.isTrue()) {
			response.setHasMore(true);
			returnedItems = returnedItems - 1;
		} else
			response.setHasMore(false);

		response.setAddPermit(true);

		response.setTotalItemsNum(returnedItems);

		int count = 0;
		for (PersonalNotesData item : items) {
			// exit in the last item
			if (count++ == returnedItems)
				break;
			String msg = null;

			if (!request.getGadgetViewState().equals(GadgetViewState.CANVAS)
					&& item.getPersonalNotesMessage().length() > 30)
				msg = item.getPersonalNotesMessage().substring(0, 30) + "...";
			else
				msg = item.getPersonalNotesMessage();

			ContentRecord record = response.newItem();

			record.addItemKeyField(item.getContentItemKey());
			record.addItemField(Params.MESSAGE.getParamName(), msg);
			record.addItemField(Params.PRIORITY.getParamName(), new Integer(
					item.getPriority()).toString());

			List<SharedItemReff> shares = item.getSharedItemReff();
			boolean isOwner = false;
			boolean isEditor = false;

			if (shares != null) {

				for (SharedItemReff share : shares) {
					if (share.getSharedWithId().equals(
							request.getCurrentUserProfileId())
							&& share.getSharingType().equals(SharingType.OWNER)) {
						isOwner = true;
						isEditor = true;
					}

					if (share.getSharedWithId().equals(
							request.getCurrentUserProfileId())
							&& share.getSharingType().equals(SharingType.EDIT))
						isEditor = true;
				}

				record.setGadgetPermissions(isEditor, isOwner, isOwner);

				if (!isOwner) {
					// send info about the owner
					UserProfile owner = UserProfilesUtils.getProfileById(item
							.getOwnerId());

					if (owner != null && !owner.isPrivate()) {
						if (owner.getNickName() != null)
							record.addItemField(ProfileFields.PROFILE_NICKNAME
									.getParamName(), owner.getNickName());
						if (owner.getPhotoUrl() != null
								&& owner.getPhotoUrl().length() > 0)
							record.addItemField(
									ProfileFields.PROFILE_THUMBNAILURL
											.getParamName(), owner
											.getPhotoUrl());

					}

				}
			}

		}

	}

	
	
}
